#ifndef TCPCONN_H
#define TCPCONN_H

#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <assert.h>
#include <sys/stat.h>
#include <string.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <stdarg.h>
#include <vector>
#include <map>
#include <set>
#include "../locker/locker.h"
#include "../sqlpool/sql.h"
#include "../url/url.h"

/*文件名的最大长度*/
    static const int FILENAME_LEN = 200;
/*读缓冲区的大小*/
    static const int READ_BUFFER_SIZE = 1024;
/*写缓冲区的大小*/
    static const int WRITE_BUFFER_SIZE = 1024;
class tcpconn
{
    
public:
    void close_conn(bool real_close=true);
    void init(int sockfd, const sockaddr_in &addr);
    void init();

    void tcpread(); //读取数据到读缓冲区
//解析缓冲区数据
    void process_read(int);
//以下函数被process_read()调用
    void deal_reload();
    void deal_login();
    void deal_signup();
    void deal_upload();
    void deal_download();
    void deal_trans();
    void process_write();
//以下函数被tcpwrite()调用，用于向客户端写内容
    void send_reload();
    void send_login();
    void send_signup();
    void send_upload();
    void send_download();
//向客户端写
    void tcpwrite();
//线程池处理函数
    void process();

public:
    /*所有socket上的事件都被注册到同一个epoll内核事件表中，所以将epoll文件描述符设置为静态的*/
    static int m_epollfd;
    static int m_user_count;
    static connection_pool* connpool;

private:
    /*该TCP连接的socket和对方的sockt地址*/
    int m_sockfd;
    sockaddr_in m_address;
    /*读缓冲区*/
    char m_read_buf[READ_BUFFER_SIZE];
    /*写缓冲区*/
    char m_write_buf[WRITE_BUFFER_SIZE];


    /*请求类型*/
    char  m_type[10];
    /*请求内容*/
    char m_data[256];

    /*客户请求的目标文件的完整路径，其内容等于doc_root+m_url,doc_root是网站的根目录*/
    char m_real_file[FILENAME_LEN];
    /*客户请求的目标文件的文件名*/
    char m_url[256];
    /*客户请求的目标文件被mmap到内存的起始位置*/
    char *m_file_address;
    /*目标文件的状态，通过它可以判断文件是否存在，是否为目录，是否可读，并获取文件大小等信息*/
    struct stat m_file_stat;

    vector<string> m_resources; //数据库资源表
    
    
    int bytes_to_send;
    int bytes_have_send;
    int res_have_send;

    bool m_upload;
    bool m_login;
    bool m_signup;
    bool m_trans;
    int m_upload_fd;
};



#endif
